﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
using NiuX.Domain.Repositories;

namespace NiuX.EntityFramework
{
    public class EfCoreQueryableProvider : IQueryableProvider
    {
        public bool CanExecute<T>(IQueryable<T> queryable)
        {
            return queryable.Provider is EntityQueryProvider;
        }

        public bool Contains<T>(IQueryable<T> queryable, T item)
        {
            return queryable.Contains(item);
        }

        public bool Any<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.Any(predicate);
        }

        public bool All<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.All(predicate);
        }

        public int Count<T>(IQueryable<T> queryable)
        {
            return queryable.Count();
        }

        public int Count<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.Count(predicate);
        }

        public long LongCount<T>(IQueryable<T> queryable)
        {
            return queryable.LongCount();
        }

        public long LongCount<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.LongCount(predicate);
        }

        public T First<T>(IQueryable<T> queryable)
        {
            return queryable.First();
        }

        public T First<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.First(predicate);
        }

        public T FirstOrDefault<T>(IQueryable<T> queryable)
        {
            return queryable.FirstOrDefault();
        }

        public T FirstOrDefault<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.FirstOrDefault(predicate);
        }

        public T Last<T>(IQueryable<T> queryable)
        {
            return queryable.Last();
        }

        public T Last<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.Last(predicate);
        }

        public T LastOrDefault<T>(IQueryable<T> queryable)
        {
            return queryable.LastOrDefault();
        }

        public T LastOrDefault<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.LastOrDefault(predicate);
        }

        public T Single<T>(IQueryable<T> queryable)
        {
            return queryable.Single();
        }

        public T Single<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.Single(predicate);
        }

        public T SingleOrDefault<T>(IQueryable<T> queryable)
        {
            return queryable.SingleOrDefault();
        }

        public T SingleOrDefault<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate)
        {
            return queryable.SingleOrDefault(predicate);
        }

        public T Min<T>(IQueryable<T> queryable)
        {
            return queryable.Min();
        }

        public TResult Min<T, TResult>(IQueryable<T> queryable, Expression<Func<T, TResult>> selector)
        {
            return queryable.Min(selector);
        }

        public T Max<T>(IQueryable<T> queryable)
        {
            return queryable.Max();
        }

        public TResult Max<T, TResult>(IQueryable<T> queryable, Expression<Func<T, TResult>> selector)
        {
            return queryable.Max(selector);
        }

        public decimal Sum(IQueryable<decimal> source)
        {
            return source.Sum();
        }

        public decimal? Sum(IQueryable<decimal?> source)
        {
            return source.Sum();
        }

        public decimal Sum<T>(IQueryable<T> queryable, Expression<Func<T, decimal>> selector)
        {
            return queryable.Sum(selector);
        }

        public decimal? Sum<T>(IQueryable<T> queryable, Expression<Func<T, decimal?>> selector)
        {
            return queryable.Sum(selector);
        }

        public int Sum(IQueryable<int> source)
        {
            return source.Sum();
        }

        public int? Sum(IQueryable<int?> source)
        {
            return source.Sum();
        }

        public int Sum<T>(IQueryable<T> queryable, Expression<Func<T, int>> selector)
        {
            return queryable.Sum(selector);
        }

        public int? Sum<T>(IQueryable<T> queryable, Expression<Func<T, int?>> selector)
        {
            return queryable.Sum(selector);
        }

        public long Sum(IQueryable<long> source)
        {
            return source.Sum();
        }

        public long? Sum(IQueryable<long?> source)
        {
            return source.Sum();
        }

        public long Sum<T>(IQueryable<T> queryable, Expression<Func<T, long>> selector)
        {
            return queryable.Sum(selector);
        }

        public long? Sum<T>(IQueryable<T> queryable, Expression<Func<T, long?>> selector)
        {
            return queryable.Sum(selector);
        }

        public double Sum(IQueryable<double> source)
        {
            return source.Sum();
        }

        public double? Sum(IQueryable<double?> source)
        {
            return source.Sum();
        }

        public double Sum<T>(IQueryable<T> queryable, Expression<Func<T, double>> selector)
        {
            return queryable.Sum(selector);
        }

        public double? Sum<T>(IQueryable<T> queryable, Expression<Func<T, double?>> selector)
        {
            return queryable.Sum(selector);
        }

        public float Sum(IQueryable<float> source)
        {
            throw new NotImplementedException();
        }

        public float? Sum(IQueryable<float?> source)
        {
            throw new NotImplementedException();
        }

        public float Sum<T>(IQueryable<T> queryable, Expression<Func<T, float>> selector)
        {
            throw new NotImplementedException();
        }

        public float? Sum<T>(IQueryable<T> queryable, Expression<Func<T, float?>> selector)
        {
            throw new NotImplementedException();
        }

        public decimal Average(IQueryable<decimal> source)
        {
            throw new NotImplementedException();
        }

        public decimal? Average(IQueryable<decimal?> source)
        {
            throw new NotImplementedException();
        }

        public decimal Average<T>(IQueryable<T> queryable, Expression<Func<T, decimal>> selector)
        {
            throw new NotImplementedException();
        }

        public decimal? Average<T>(IQueryable<T> queryable, Expression<Func<T, decimal?>> selector)
        {
            throw new NotImplementedException();
        }

        public double Average(IQueryable<int> source)
        {
            throw new NotImplementedException();
        }

        public double? Average(IQueryable<int?> source)
        {
            throw new NotImplementedException();
        }

        public double Average<T>(IQueryable<T> queryable, Expression<Func<T, int>> selector)
        {
            throw new NotImplementedException();
        }

        public double? Average<T>(IQueryable<T> queryable, Expression<Func<T, int?>> selector)
        {
            throw new NotImplementedException();
        }

        public double Average(IQueryable<long> source)
        {
            throw new NotImplementedException();
        }

        public double? Average(IQueryable<long?> source)
        {
            throw new NotImplementedException();
        }

        public double Average<T>(IQueryable<T> queryable, Expression<Func<T, long>> selector)
        {
            throw new NotImplementedException();
        }

        public double? Average<T>(IQueryable<T> queryable, Expression<Func<T, long?>> selector)
        {
            throw new NotImplementedException();
        }

        public double Average(IQueryable<double> source)
        {
            throw new NotImplementedException();
        }

        public double? Average(IQueryable<double?> source)
        {
            throw new NotImplementedException();
        }

        public double Average<T>(IQueryable<T> queryable, Expression<Func<T, double>> selector)
        {
            throw new NotImplementedException();
        }

        public double? Average<T>(IQueryable<T> queryable, Expression<Func<T, double?>> selector)
        {
            throw new NotImplementedException();
        }

        public float Average(IQueryable<float> source)
        {
            throw new NotImplementedException();
        }

        public float? Average(IQueryable<float?> source)
        {
            throw new NotImplementedException();
        }

        public float Average<T>(IQueryable<T> queryable, Expression<Func<T, float>> selector)
        {
            throw new NotImplementedException();
        }

        public float? Average<T>(IQueryable<T> queryable, Expression<Func<T, float?>> selector)
        {
            throw new NotImplementedException();
        }

        public List<T> ToList<T>(IQueryable<T> queryable)
        {
            throw new NotImplementedException();
        }

        public T[] ToArray<T>(IQueryable<T> queryable)
        {
            throw new NotImplementedException();
        }
    }
}
